/*
 * NetworkManager.hpp
 *
 *  Created on: Dec 11, 2014
 *      Author: toti
 */

#ifndef IBRCNETWORKMANAGER_HPP_
#define IBRCNETWORKMANAGER_HPP_

#include <list>

#include <Connectivity/ConnectionManager.hpp>
#include <Network/LocalNode.hpp>
#include <Network/LocalClient.hpp>
#include <Network/LocalServer.hpp>
#include <Network/NetworkChannel.hpp>
#include <Network/NetworkClient.hpp>
#include <Network/NetworkServer.hpp>
#include <Network/NetworkRequests/NetworkRequest.hpp>
#include <Network/NetworkRequests/CreateChannelNetworkRequest.hpp>
#include <Network/NetworkRequests/CreateNickNetworkRequest.hpp>
#include <Network/NetworkRequests/RemoveChannelNetworkRequest.hpp>
#include <Network/MessagePackages/MessagePackage.hpp>
#include <Network/MessagePackages/ClientMessagePackage.hpp>
#include <Network/MessagePackages/ServerMessagePackage.hpp>

class IBRCNetworkManager{

private:

	ConnectionManager *connectionManager;

	std::list<NetworkServer*> *networkServerList;
	std::list<NetworkClient*> *networkClientList;
	std::list<NetworkChannel*> *networkChannelList;
	std::list<NetworkRequest*> *networkRequestList;

	int defaultNickNumber;
	int requestIdNumber;

	/*
	 * Server functions
	 */
	void processServerMessagePackage(ServerMessagePackage *serverMessagePackage);

	void processServerRegistration(ServerMessagePackage *package);
	void processServerNickRemove(ServerMessagePackage *package);
	void processServerChannelJoin(ServerMessagePackage *package);
	void processServerChannelLeave(ServerMessagePackage *package);
	void processServerChannelSetTopic(ServerMessagePackage *package);
	void processServerChannelMessage(ServerMessagePackage *package);
	void processServerChannelPrivateMessage(ServerMessagePackage *package);
	void processServerRequestNickCreate(ServerMessagePackage *package);
	void processServerRequestChannelCreate(ServerMessagePackage *package);
	void processServerRequestChannelRemove(ServerMessagePackage *package);
	void processServerResponse(ServerMessagePackage *package);
	void processServerRequestAccepted(NetworkRequest *networkRequest);
	void processServerRequestRejected(NetworkRequest *networkRequest);


	/*
	 * Client functions
	 */
	void processClientMessagePackage(ClientMessagePackage *clientMessagePackage);

	void processClientRegistrationMessage(ClientMessagePackage *clientMessagePackage);
	void processClientChannelMessage(ClientMessagePackage *clientMessagePackage);
	void processClientGettopicMessage(ClientMessagePackage *clientMessagePackage);
	void processClientJoinMessage(ClientMessagePackage *clientMessagePackage);
	void processClientLeaveMessage(ClientMessagePackage *clientMessagePackage);
	void processClientListMessage(ClientMessagePackage *clientMessagePackage);
	void processClientNickMessage(ClientMessagePackage *clientMessagePackage);
	void processClientPrivateMessage(ClientMessagePackage *clientMessagePackage);
	void processClientQuitMessage(ClientMessagePackage *clientMessagePackage);
	void processClientSettopicMessage(ClientMessagePackage *clientMessagePackage);


	/*
	 * Misc
	 */
	void performForwardBroadcast(ServerMessagePackage *serverMessagePackage);
	void performCompleteBroadcast(ServerMessagePackage *serverMessagePackage);
	void performChannelRemoveIfEmpty(LocalClient *localClient, NetworkChannel *networkChannel);
	void performGenerateRequestId(std::string& requestId);
	void performGenerateDefaultNick(std::string& defaultNick);
	void performResponse(std::string& requestId, bool value);

	/*
	 * List finders
	 */
	NetworkRequest *findNetworkRequestById(std::string& id);
	RemoveChannelNetworkRequest *findRemoveChannelNetworkRequestByName(std::string& name);
	NetworkClient *findNetworkClientByName(std::string& name);
	void findNetworkClientsByChannel(std::list<NetworkClient*> *clientList, NetworkChannel *networkChannel);
	NetworkChannel *findNetworkChannelByName(std::string& name);
	void findNetworkChannelByOwner(std::list<NetworkChannel*> *channelList, NetworkClient *networkClient);
	NetworkServer *findNetworkServerByName(std::string& name);
	void findNetworkServerByClients(std::list<NetworkServer*> *serverList, std::list<NetworkClient*> *clientList);
	void findLocalServerByNetworkServer(std::list<LocalServer*> *localServerList, std::list<NetworkServer*> *networkServerList);
	CreateChannelNetworkRequest *findCreateChannelNetworkRequestByName(std::string& name);
	CreateNickNetworkRequest *findCreateNickNetworkRequestByName(std::string& name);

public:

	IBRCNetworkManager(ConnectionManager *connectionManager);

	void processData();

	static std::list<MessagePackage*> *getInboundMessagePackageList();
	static std::list<MessagePackage*> *getOutboundMessagePackageList();


	std::list<NetworkServer*> *getNetworkServerList();
	std::list<NetworkClient*> *getNetworkClientList();
	std::list<NetworkChannel*> *getNetworkChannelList();
	std::list<NetworkRequest*> *getNetworkRequestList();

};


#endif /* NETWORKMANAGER_HPP_ */
